#include <string.h>

#include "lib.h"
#include "msgplug.h"

MsgPlugs::MsgPlugs()
{
	numPlugs = 0;
	plugs = (MsgPlug**)0;
	empty = '\0';
}

MsgPlugs::~MsgPlugs()
{
	if (plugs)
	{
		int32 i;

		for (i = 0; i < numPlugs; i++)
			delete plugs[i];

		delete [] plugs;
		plugs = (MsgPlug**)0;
	}
}

bool8
MsgPlugs::add(MsgPlug* newPlug)
{
	MsgPlug** newplugs = new MsgPlug*[numPlugs + 1];

	if (newplugs)
	{
		if (numPlugs > 0)
			memcpy(newplugs, plugs, numPlugs * sizeof(MsgPlug*));

		delete [] plugs;
		plugs = newplugs;

		plugs[numPlugs++] = newPlug;
		return true;
	}
	else
	{
		delete newPlug;
		return false;
	}
}

int32
MsgPlugs::getLen(int32 index)
{
	if (index >= 0 && index < numPlugs && plugs[index])
		return plugs[index]->getLen();
	return 0;
}

char*
MsgPlugs::getText(int32 index)
{
	char* result = (char*)0;

	if (index >= 0 && index < numPlugs && plugs[index])
		result = plugs[index]->getText();

	return result ? result : &empty;
}

void
MsgPlugs::setValue(int32 index, ...)
{
	va_list args;

	va_start(args, index);

	if (index >= 0 && index < numPlugs && plugs[index])
		plugs[index]->setValue(args);

	va_end(args);
}

void
MsgPlugs::reset(int32 index)
{
	if (index >= 0 && index < numPlugs && plugs[index])
		plugs[index]->reset();
}

//
// ------------------------------------- MsgPlug Subclasses -------------------------------------
//

NullTermCharArrayMsgPlug::NullTermCharArrayMsgPlug(
	char* NullTermNeverNullPointer, int32 maxlen)
{
	ASSERT(NullTermNeverNullPointer != (char*)0);

	str = NullTermNeverNullPointer;
	len = strlen(str);
	this->maxlen = maxlen;
}

void
NullTermCharArrayMsgPlug::setValue(va_list args)
{
	char* src = va_arg(args, char*);

	if (src)
	{
		len = strlen(src);
		if (len < maxlen)
			strcpy(str, src);
		else
		{
			len = maxlen - 1;
			memcpy(str, src, len);
			str[len] = '\0';
		}
	}
	else
	{
		str[0] = '\0';
		len = 0;
	}
}

void
NullTermCharArrayMsgPlug::reset()
{
	len = 0;
	str[len] = '\0';
}

Int32MsgPlug::Int32MsgPlug()
	 : NullTermCharArrayMsgPlug()
{
	len = 0;
	val = 0;
	converted = false;

	str = asciiint;
	maxlen = MAXASCIIINT + 1;

	reset();
}

int32
Int32MsgPlug::getLen()
{
	if (!converted)
		convert();

	return NullTermCharArrayMsgPlug::getLen();
}

char*
Int32MsgPlug::getText()
{
	if (!converted)
		convert();

	return NullTermCharArrayMsgPlug::getText();
}

void
Int32MsgPlug::setValue(va_list args)
{
	int32 newVal = va_arg(args, int32);

	if (newVal == val && converted)
		/* do nothing */ ;
	else
	{
		val = newVal;
		converted = false;
	}
}

void
Int32MsgPlug::reset()
{
	len = 0;
	asciiint[len++] = '0';
	asciiint[len] = '\0';
	val = 0;
	converted = true;
}

void
Int32MsgPlug::convert()
{
	int32 i, j, isNeg, src;
	char temp;

	isNeg = val < 0;
	src = isNeg ? -val : val;

	i = 0;
	while (src)
	{
		asciiint[i++] = '0' + (src % 10);
		src /= 10;
	}

	if (i == 0)
		asciiint[i++] = '0';

	if (isNeg)
		asciiint[i++] = '-';

	asciiint[i] = '\0';
	len = i;

	for (j = 0, --i; j < i; j++, --i)
	{
		temp = asciiint[i];
		asciiint[i] = asciiint[j];
		asciiint[j] = temp;
	}

	converted = true;

	ASSERT(len <= MAXASCIIINT);
}

MoneyMsgPlug::MoneyMsgPlug( char *currency)
	 : NullTermCharArrayMsgPlug()
{
	len = 0;
	val = 0;
	converted = false;

	str = money;
	maxlen = MAXMONEY + 1;
	
	curL = strlen(currency);
	this->currency = new char[ curL+1 ];
	if( this->currency )  strcpy(this->currency,currency);

	reset();
}

MoneyMsgPlug::~MoneyMsgPlug()
{
	if( this->currency )  delete [] this->currency;
}

int32
MoneyMsgPlug::getLen()
{
	if (!converted)
		convert();

	return NullTermCharArrayMsgPlug::getLen();
}

char*
MoneyMsgPlug::getText()
{
	if (!converted)
		convert();

	return NullTermCharArrayMsgPlug::getText();
}

void
MoneyMsgPlug::setValue(va_list args)
{
	int32 newVal = va_arg(args, int32);

	if (newVal == val && converted)
		/* do nothing */ ;
	else
	{
		val = newVal;
		converted = false;
	}
}

void
MoneyMsgPlug::reset()
{
	len = 0;
	
	if( currency )
	{
		char *p=currency;
		while( *p ) money[len++] = *p++;
	}

	money[len++] = '0';
	money[len++] = '.';
	money[len++] = '0';
	money[len++] = '0';
	money[len] = '\0';
	val = 0;
	converted = true;

}

void
MoneyMsgPlug::convert()
{
	int32 i, j, isNeg, cents, numDigits;
	char temp;

	isNeg = val < 0;
	cents = isNeg ? -val : val;

	i = numDigits = 0;
	while (cents)
	{
		money[i++] = '0' + (cents % 10);
		cents /= 10;
		++numDigits;

		if (i == 2) money[i++] = '.';
		if (numDigits >= 5 && cents && ((numDigits - 2) % 3) == 0)	money[i++] = ',';
	}

	while (i < 4)
		if (i == 2)
			money[i++] = '.';
		else
			money[i++] = '0';

	if (isNeg)
		money[i++] = '-';

	if( currency )
	{
		for(int c=curL; c; c-- )  money[i++] = currency[c-1];
	}

	money[i] = '\0';
	len = i;

	for (j = 0, --i; j < i; j++, --i)
	{
		temp = money[i];
		money[i] = money[j];
		money[j] = temp;
	}

	converted = true;

	ASSERT(len <= MAXMONEY);
}
